<!--
 * @Author: ningjp
 * @Date: 2023-01-28
 * @Description: //虚拟下拉列表，解决数据过多导致卡顿
-->
<template>
  <div>
    <el-select :value="defaultValue" popper-class="virtualselect" filterable :filter-method="filterMethod" @visible-change="visibleChange" v-bind="$attrs" v-on="$listeners">
      <virtual-list ref="virtualList" class="virtualselect-list"
                    :data-key="value"
                    :data-sources="selectArr"
                    :data-component="itemComponent"
                    :keeps="10"
                    :extra-props="{
                    label: label,
                    value: value,
                    isRight: isRight,
                }"></virtual-list>
    </el-select>
  </div>
</template>
<script>
import virtualList from 'vue-virtual-scroll-list'
import ElOptionNode from './el-option-node'
export default {
  components: {
    'virtual-list': virtualList
  },
  model: {
    prop: 'defaultValue',
    event: 'change'
  },
  props: {
    selectData: {
      type: Object,
      default() {
        return {}
      }
    }, // 父组件传的值
    // 数组
    list: {
      type: Array,
      default() {
        return []
      }
    },
    // 显示名称
    label: {
      type: String,
      default: ''
    },
    // 标识
    value: {
      type: String,
      default: ''
    },
    // 显示右边
    isRight: {
      type: Boolean,
      default: false
    },
    defaultValue: {
      type: String,
      default: ''
    } // 绑定的默认值
  },
  mounted() {
    this.init();
  },
  watch: {
    'list'() {
      this.init();
    }
  },
  data() {
    return {
      itemComponent: ElOptionNode,
      selectArr: []
    }
  },
  methods: {
    init() {
      if (!this.defaultValue) {
        this.selectArr = this.list;
      } else {
        // 回显问题
        // 由于只渲染20条数据,当默认数据处于20条之外,在回显的时候会显示异常
        // 解决方法:遍历所有数据,将对应回显的那一条数据放在第一条即可
        this.selectArr = JSON.parse(JSON.stringify(this.list));
        let obj = {};
        for (let i = 0; i < this.selectArr.length; i++) {
          const element = this.selectArr[i];

          if (element[this.value].toLowerCase() === this.defaultValue.toLowerCase()) {
            obj = element;
            this.selectArr.splice(i, 1);
            break;
          }
        }
        this.selectArr.unshift(obj);
      }
    },
    // 搜索
    filterMethod(query) {
      if (query !== '') {
        this.$refs.virtualList.scrollToIndex(0);// 滚动到顶部
        setTimeout(() => {
          this.selectArr = this.list.filter(item => {
            return this.selectData.isRight
              ? (item[this.label].toLowerCase().indexOf(query.toLowerCase()) > -1 || item[this.value].toLowerCase().indexOf(query.toLowerCase()) > -1)
              : item[this.label].toLowerCase().indexOf(query.toLowerCase()) > -1;
          });
        }, 100)
      } else {
        this.init();
      }
    },
    visibleChange(bool) {
      if (!bool) {
        this.$refs.virtualList.reset();
        this.init();
      }
    }
  }
}
</script>
<style lang="less" scoped>
.virtualselect {
  // 设置最大高度
  &-list {
    max-height:245px;
    overflow-y:auto;
  }
}
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
  background-color: transparent;
  cursor: pointer;
  margin-right: 5px;
}
::-webkit-scrollbar-thumb {
  background-color: rgba(144,147,153,.3) !important;
  border-radius: 3px !important;
}
::-webkit-scrollbar-thumb:hover{
  background-color: rgba(144,147,153,.5) !important;
}
::-webkit-scrollbar-track {
  background-color: transparent !important;
  border-radius: 3px !important;
  -webkit-box-shadow: none !important;
}
</style>
